﻿/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace DaveSexton.DocProject
{
	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable")]
	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
	public class DialogSettings<T> : IsolatedSettingsDictionary<string, string>
		where T : Form
	{
		#region Public Properties
		public Rectangle Bounds
		{
			get
			{
				return Read("bounds", Rectangle.Empty);
			}
			set
			{
				Write("bounds", value);
			}
		}

		public T Dialog
		{
			get
			{
				return dialog;
			}
		}

		public bool Loading
		{
			get
			{
				return loading;
			}
		}
		#endregion

		#region Private / Protected
		private readonly T dialog;
		private bool loading;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="DialogSettings" /> class.
		/// </summary>
		public DialogSettings(T dialog, Guid uniqueDialogId)
			: base(System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForAssembly(), uniqueDialogId.ToString() + ".xml",
			System.Globalization.CultureInfo.InvariantCulture)
		{
			if (dialog == null)
				throw new ArgumentNullException("dialog");

			this.dialog = dialog;

			dialog.LocationChanged += dialog_LocationChanged;
			dialog.SizeChanged += dialog_SizeChanged;
		}
		#endregion

		#region Methods
		private static bool ContainsOrEquals(Size outerSize, Size innerSize)
		{
			return
				innerSize.Width <= outerSize.Width &&
				innerSize.Height <= outerSize.Height;
		}

		public void Load()
		{
			loading = true;

			try
			{
				Rectangle bounds = this.Bounds;

				if (bounds != Rectangle.Empty)
				{
					if ((dialog.MinimumSize == Size.Empty || ContainsOrEquals(bounds.Size, dialog.MinimumSize))
						&& (dialog.MaximumSize == Size.Empty || ContainsOrEquals(dialog.MaximumSize, bounds.Size)))
					{
						dialog.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
						dialog.Bounds = bounds;
					}
					else
						this.Bounds = dialog.Bounds;
				}

				LoadInternal();
			}
			finally
			{
				loading = false;
			}
		}

		protected virtual void LoadInternal()
		{
			// for derived types
		}
		#endregion

		#region Event Handlers
		private void dialog_SizeChanged(object sender, EventArgs e)
		{
			if (!loading)
				this.Bounds = dialog.Bounds;
		}

		private void dialog_LocationChanged(object sender, EventArgs e)
		{
			if (!loading)
				this.Bounds = dialog.Bounds;
		}
		#endregion
	}
}
